package br.net.woodstock.tickettoride.client.web;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import br.net.woodstock.rockframework.utils.CollectionUtils;
import br.net.woodstock.rockframework.utils.ConditionUtils;
import br.net.woodstock.tickettoride.client.beans.MapTicketConverter;

public class RequestParameterTargetHandler implements TargetHandler {

	private static final MapTicketConverter	CONVERTER	= new MapTicketConverter();

	@Override
	public HttpServletRequest handle(final HttpServletRequest request, final byte[] bytes) {
		Map<String, String> data = RequestParameterTargetHandler.CONVERTER.fromBytes(bytes);
		Map<String, String[]> parameters = new HashMap<String, String[]>();
		for (Entry<String, String> entry : data.entrySet()) {
			parameters.put(entry.getKey(), new String[] { entry.getValue() });
		}
		return new DelegateHttpServletRequest(request, parameters);
	}

	public static class DelegateHttpServletRequest extends HttpServletRequestWrapper {

		private Map<String, String[]>	parameters;

		public DelegateHttpServletRequest(final HttpServletRequest request, final Map<String, String[]> parameters) {
			super(request);
			this.parameters = parameters;
		}

		@Override
		public String getParameter(final String name) {
			String[] array = this.parameters.get(name);
			String parameter = null;
			if (ConditionUtils.isNotEmpty(array)) {
				parameter = array[0];
			}

			if (parameter == null) {
				parameter = super.getParameter(name);
			}
			return parameter;
		}

		@Override
		@SuppressWarnings("unchecked")
		public Map<String, String[]> getParameterMap() {
			Map<String, String[]> map = new HashMap<String, String[]>();
			map.putAll(super.getParameterMap());
			map.putAll(this.parameters);
			return map;
		}

		@Override
		@SuppressWarnings("unchecked")
		public Enumeration<String> getParameterNames() {
			Set<String> set = CollectionUtils.toSet(super.getParameterNames());
			set.addAll(this.parameters.keySet());
			return CollectionUtils.toEnumeration(set);
		}

		@Override
		public String[] getParameterValues(final String name) {
			String[] parameters = this.parameters.get(name);
			if (parameters == null) {
				parameters = super.getParameterValues(name);
			}
			return parameters;
		}

	}

}
